<template>
  <div class="trend-container">
    <!-- 头部时间显示 -->
    <div class="header">
      <h2>变化查询分析</h2>
      <div class="time-control">
        <span>当前模拟时间：</span>
        <el-tag type="info">{{ formattedTime }}</el-tag>
        <el-button
            type="primary"
            size="small"
            :icon="Refresh"
            style="margin-left: 10px"
            @click="reloadCurrentView"
        >
          刷新
        </el-button>
      </div>
    </div>

    <!-- 主选项卡 -->
    <el-tabs v-model="activeTab" class="main-tabs" @tab-change="handleTabChange">
      <!-- 1. 新闻生命周期查询 -->
      <el-tab-pane label="新闻生命周期" name="lifecycle">
        <el-card class="query-card">
          <div class="query-row">
            <div class="query-item">
              <span class="query-label">时间范围：</span>
              <el-date-picker
                  v-model="lifecycleTimeRange"
                  :default-value="defaultTimeRange"
                  :default-time="defaultTimeRange"
                  :clearable="false"
                  type="datetimerange"
                  range-separator="至"
                  :disabled-date="disableFutureDates"
                  :disabled-hours="disableFutureHours"
                  :disabled-minutes="disableFutureMinutes"
                  :disabled-seconds="disableFutureSeconds"
                  size="small"
              />
            </div>
            <div class="query-item">
              <span class="query-label">新闻ID：</span>
              <el-input
                  v-model="newsLifecycleParams.newsId"
                  placeholder="输入新闻ID"
                  clearable
                  size="small"
                  style="width: 200px"
              />
            </div>
            <el-button
                type="primary"
                size="small"
                @click="fetchNewsLifecycle"
            >
              查询
            </el-button>
          </div>

          <div v-if="newsLifecycleData.length" class="info-container">
            <el-descriptions :column="2" border>
              <el-descriptions-item label="新闻ID">{{ lifecycle_fetched_data.news_id }}</el-descriptions-item>
              <el-descriptions-item label="起始时间">{{ lifecycle_fetched_data.start_time }}</el-descriptions-item>
              <el-descriptions-item label="截止时间">{{ lifecycle_fetched_data.end_time }}</el-descriptions-item>
              <el-descriptions-item label="总点击量">
                {{ lifecycle_fetched_data.lifecycle_total_clickcount }}
              </el-descriptions-item>
              <el-descriptions-item label="总停留时间(秒)">
                {{ lifecycle_fetched_data.lifecycle_total_dwelltime }}
              </el-descriptions-item>
            </el-descriptions>
          </div>

          <div v-if="newsLifecycleData.length" class="chart-container">
            <el-tabs v-model="activeLifecycleTab">
              <el-tab-pane label="点击量" name="click">
                <div ref="clickChart" style="width: 100%; height: 400px;"></div>
              </el-tab-pane>
              <el-tab-pane label="停留时间" name="dwell">
                <div ref="dwellTimeChart" style="width: 100%; height: 400px;"></div>
              </el-tab-pane>
            </el-tabs>
          </div>

          <div v-else class="empty-data">
            <el-empty description="暂无数据">
              <template #description>
                <div class="empty-content">
                  <p>新闻生命周期分析说明：</p>
                  <ul>
                    <li>输入新闻ID和时间范围查询新闻的生命周期数据</li>
                    <li>可查看新闻的曝光次数和用户停留时间趋势</li>
                    <li>时间范围不能超过当前模拟时间</li>
                  </ul>
                </div>
              </template>
            </el-empty>
          </div>
        </el-card>
      </el-tab-pane>

      <!-- 2. 新闻类别统计 -->
      <el-tab-pane label="新闻类别趋势" name="category">
        <el-card class="query-card">
          <div class="query-row">
            <div class="query-item">
              <span class="query-label">时间范围：</span>
              <el-date-picker
                  v-model="categoryTimeRange"
                  :default-value="defaultTimeRange"
                  :default-time="defaultTimeRange"
                  :clearable="false"
                  type="datetimerange"
                  range-separator="至"
                  :disabled-date="disableFutureDates"
                  :disabled-hours="disableFutureHours"
                  :disabled-minutes="disableFutureMinutes"
                  :disabled-seconds="disableFutureSeconds"
                  size="small"
              />
            </div>
            <div class="query-item">
              <span class="query-label">新闻类别：</span>
              <el-input
                  v-model="categoryParams.category"
                  placeholder="输入新闻类别"
                  clearable
                  size="small"
                  style="width: 200px"
              />
            </div>
            <el-button
                type="primary"
                size="small"
                @click="fetchCategoryTrend"
            >
              查询
            </el-button>
          </div>

          <div v-if="categoryTrendData.length" class="info-container">
            <el-descriptions :column="2" border>
              <el-descriptions-item label="新闻类别">{{ category_fetched_data.category }}</el-descriptions-item>
              <el-descriptions-item label="起始时间">{{ category_fetched_data.start_time }}</el-descriptions-item>
              <el-descriptions-item label="截止时间">{{ category_fetched_data.end_time }}</el-descriptions-item>
              <el-descriptions-item label="总点击量">
                {{ category_fetched_data.total_clickcount }}
              </el-descriptions-item>
            </el-descriptions>
          </div>

          <div v-if="categoryTrendData.length" class="chart-container">
            <div ref="categoryChart" style="width: 100%; height: 400px;"></div>
          </div>

          <div v-else class="empty-data">
            <el-empty description="暂无数据">
              <template #description>
                <div class="empty-content">
                  <p>新闻类别趋势分析说明：</p>
                  <ul>
                    <li>输入新闻类别和时间范围查询该类新闻的趋势数据</li>
                    <li>可查看该类新闻的每日点击次数</li>
                    <li>时间范围不能超过当前模拟时间</li>
                  </ul>
                </div>
              </template>
            </el-empty>
          </div>
        </el-card>
      </el-tab-pane>

      <!-- 3. 用户兴趣分析 -->
      <el-tab-pane label="用户兴趣分析" name="interest">
        <el-card class="query-card">
          <div class="query-row">
            <div class="query-item">
              <span class="query-label">时间范围：</span>
              <el-date-picker
                  v-model="interestTimeRange"
                  :default-value="defaultTimeRange"
                  :default-time="defaultTimeRange"
                  :clearable="false"
                  type="datetimerange"
                  range-separator="至"
                  :disabled-date="disableFutureDates"
                  :disabled-hours="disableFutureHours"
                  :disabled-minutes="disableFutureMinutes"
                  :disabled-seconds="disableFutureSeconds"
                  size="small"
              />
            </div>
            <div class="query-item">
              <span class="query-label">用户ID：</span>
              <el-input
                  v-model="userInterestParams.userId"
                  placeholder="输入用户ID"
                  clearable
                  size="small"
                  style="width: 200px"
              />
            </div>
            <el-button
                type="primary"
                size="small"
                @click="fetchUserInterest"
            >
              查询
            </el-button>
          </div>

          <div v-if="userInterestCategoryData.length" class="info-container">
            <el-descriptions :column="2" border>
              <el-descriptions-item label="用户ID">{{ userInterst_fetched_data.user_id }}</el-descriptions-item>
              <el-descriptions-item label="起始时间">{{ userInterst_fetched_data.start_time }}</el-descriptions-item>
              <el-descriptions-item label="截止时间">{{ userInterst_fetched_data.end_time }}</el-descriptions-item>
              <el-descriptions-item label="总点击次数">
                {{ userInterestData.summary?.total_exposures || 0 }}
              </el-descriptions-item>
              <el-descriptions-item label="平均停留时间(秒)">
                {{ userInterestData.summary?.avg_dwelltime?.toFixed(2) || 0 }}
              </el-descriptions-item>
              <el-descriptions-item label="关注类别数">
                {{ userInterestData.summary?.category_count || 0 }}
              </el-descriptions-item>
            </el-descriptions>
          </div>

          <div v-if="userInterestCategoryData.length" class="table-container">
            <el-table
                :data="userInterestCategoryData"
                border
                stripe
                style="width: 100%; margin-top: 20px"
            >
              <el-table-column prop="category" label="新闻类别" align="center" />
              <el-table-column prop="exposure_count" label="曝光次数" align="center" sortable />
              <el-table-column prop="avg_dwelltime" label="平均停留时间(秒)" align="center" sortable>
                <template #default="{row}">
                  {{ row.avg_dwelltime?.toFixed(2) || 0 }}
                </template>
              </el-table-column>
              <el-table-column prop="news_count" label="新闻数量" align="center" sortable />
              <el-table-column prop="avg_body_length" label="平均内容长度" align="center" sortable/>
              <el-table-column prop="avg_headline_length" label="平均标题长度" align="center" sortable/>
            </el-table>
          </div>

          <div v-if="userInterestCategoryData.length" class="chart-container">
            <el-tabs v-model="activeInterestTab">
              <el-tab-pane label="类别分布" name="category">
                <div ref="categoryPieChart" style="width: 100%; height: 400px;"></div>
              </el-tab-pane>
              <el-tab-pane label="停留时间分析" name="dwelltime">
                <div ref="dwellTimeBarChart" style="width: 100%; height: 400px;"></div>
              </el-tab-pane>
            </el-tabs>
          </div>


          <div v-else class="empty-data">
            <el-empty description="暂无数据">
              <template #description>
                <div class="empty-content">
                  <p>用户兴趣分析说明：</p>
                  <ul>
                    <li>输入用户ID和时间范围查询用户的兴趣偏好</li>
                    <li>可查看用户对不同类别新闻的兴趣程度</li>
                    <li>时间范围不能超过当前模拟时间</li>
                  </ul>
                </div>
              </template>
            </el-empty>
          </div>
        </el-card>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>


<script setup lang="ts">
import {ref, computed,nextTick, watch} from 'vue'
import { Refresh } from '@element-plus/icons-vue'
import { useSimulationStore } from '@/store/simulation'
import { storeToRefs } from 'pinia'
import * as echarts from 'echarts'
import { ElMessage } from 'element-plus'
import axios from 'axios'

const simulationStore = useSimulationStore()
const { formattedTime, initialTime,currentTime } = storeToRefs(simulationStore)
const { formatDateTime } = simulationStore
// 当前选项卡
const activeTab = ref('lifecycle')

// 图表
const clickChart = ref<HTMLElement | null>(null)
const dwellTimeChart = ref<HTMLElement | null>(null)
const categoryChart = ref<HTMLElement | null>(null)
const categoryPieChart = ref<HTMLElement | null>(null)
const dwellTimeBarChart = ref<HTMLElement | null>(null)

// 默认时间范围
const defaultTimeRange = ref([
  initialTime.value,
  currentTime.value
])

// 时间范围控制
const lifecycleTimeRange = ref<[Date, Date]>([initialTime.value, currentTime.value])
const categoryTimeRange = ref<[Date, Date]>([initialTime.value, currentTime.value])
const interestTimeRange = ref<[Date, Date]>([initialTime.value, currentTime.value])

// 时间规则
const disableFutureDates = (time: Date) => {
  return time > currentTime.value || time < initialTime.value
}
const disableFutureHours = () => {
  const now = currentTime.value
  return Array.from({length: 24}, (_, i) => i)
      .filter(h => h > now.getHours())
}
const disableFutureMinutes = (selectedHour: number) => {
  const now = currentTime.value
  if (selectedHour > now.getHours()) {
    return Array.from({length: 60}, (_, i) => i)
  }
  return Array.from({length: 60}, (_, i) => i)
      .filter(m => m > now.getMinutes())
}
const disableFutureSeconds = (selectedHour: number, selectedMinute: number) => {
  const now = currentTime.value
  if (selectedHour > now.getHours() ||
      (selectedHour === now.getHours() && selectedMinute > now.getMinutes())) {
    return Array.from({length: 60}, (_, i) => i)
  }
  return Array.from({length: 60}, (_, i) => i)
      .filter(s => s > now.getSeconds())
}


// 单新闻生命周期相关参数
const newsLifecycleParams = ref({ newsId: '' })
const newsLifecycleData = ref<Array<{
  date: string
  exposure_count: number
  total_dwelltime: number
}>>([])
const activeLifecycleTab = ref('click')
const lifecycle_fetched_data = ref({
  lifecycle_total_dwelltime: 0,
  lifecycle_total_clickcount:0,
  start_time:"",
  end_time:"",
  news_id:""
})
// 新闻类别趋势相关参数与数据
const categoryParams = ref({ category: '' })
const categoryTrendData = ref<Array<{
  date: string
  exposure_count: number
}>>([])
const category_fetched_data = ref({
  category:"",
  total_clickcount:0,
  start_time:"",
  end_time:"",
})

// 用户兴趣相关参数与数据
const userInterestParams = ref({ userId: '' })
const userInterestCategoryData = ref<Array<any>>([])
const activeInterestTab = ref('category')
const userInterestData = ref({
  by_category: [],
  summary: {
    avg_dwelltime: 0,
    category_count: 0,
    total_exposures: 0,
    total_news: 0,
    user_count: 0
  }
})
const userInterst_fetched_data = ref({})

// 表单正确性检验
const isLifecycleFormValid = computed(() => {
  return !!newsLifecycleParams.value.newsId && lifecycleTimeRange.value?.length === 2
})
const isCategoryFormValid = computed(() => {
  return !!categoryParams.value.category && categoryTimeRange.value?.length === 2
})
const isInterestFormValid = computed(() => {
  return !!userInterestParams.value.userId && interestTimeRange.value?.length === 2
})

// 处理选项卡切换逻辑
const handleTabChange = () => {
  resetTimeRanges()
  resetFormData()
  resetChartData()
  activeLifecycleTab.value = 'click'
  activeInterestTab.value = 'category'
}
// 重新加载界面
const reloadCurrentView = () => {
  handleTabChange()
  activeTab.value = 'lifecycle'
}

// 数据获取
const fetchNewsLifecycle = async () => {
  if (!isLifecycleFormValid.value) {
    ElMessage.error('请完整填写表单信息！')
    return
  }

  try {
    const [startTime, endTime] = lifecycleTimeRange.value
    const [exposureRes, dwellTimeRes] = await Promise.all([
      axios.get('http://localhost:5000/get_news_exposure_count', {
        params: {
          clicknews_id: newsLifecycleParams.value.newsId,
          start_time: formatDateTime(startTime),
          end_time: formatDateTime(endTime)
        }
      }),
      axios.get('http://localhost:5000/get_dwelltime_sum', {
        params: {
          clicknews_id: newsLifecycleParams.value.newsId,
          start_time: formatDateTime(startTime),
          end_time: formatDateTime(endTime)
        }
      })
    ])
    if(!exposureRes.data.data.total_count){
      ElMessage.warning("未查询到相关信息！")
      return
    }
    const exposureData = exposureRes.data.data.daily_exposure_counts
    const dwellTimeData = dwellTimeRes.data.data.daily_dwelltimes

    newsLifecycleData.value = exposureData.map((item:any) => ({
      date: item.date,
      exposure_count: item.exposure_count,
      total_dwelltime: dwellTimeData.find((d:any) => d.date === item.date)?.total_dwelltime || 0
    }))
    lifecycle_fetched_data.value.news_id = dwellTimeRes.data.data.clicknews_id
    lifecycle_fetched_data.value.lifecycle_total_dwelltime = dwellTimeRes.data.data.total_sum
    lifecycle_fetched_data.value.lifecycle_total_clickcount = exposureRes.data.data.total_count
    lifecycle_fetched_data.value.start_time = formatDateTime(startTime)
    lifecycle_fetched_data.value.end_time = formatDateTime(endTime)
    await nextTick(() => {
      renderClickChart()
      renderDwellTimeChart()
    })
  } catch (error) {
    ElMessage.error('获取数据失败')
    console.error(error)
  }
}
const fetchCategoryTrend = async () => {
  if (!isCategoryFormValid.value) {
    ElMessage.error('请完整填写表单信息！')
    return
  }

  try {
    const [startTime, endTime] = categoryTimeRange.value

    const res = await axios.get('http://localhost:5000/get_category_exposure_count', {
      params: {
        news_category: categoryParams.value.category,
        start_time: formatDateTime(startTime),
        end_time: formatDateTime(endTime)
      }
    })
    if(!res.data.data.total_count){
      ElMessage.warning("未查询到相关信息！")
      return
    }
    categoryTrendData.value = res.data.data.daily_exposure_counts
    category_fetched_data.value.category = res.data.data.news_category
    category_fetched_data.value.total_clickcount = res.data.data.total_count
    category_fetched_data.value.start_time = formatDateTime(startTime)
    category_fetched_data.value.end_time = formatDateTime(endTime)
    await nextTick(() => {
      renderCategoryChart()
    })
  } catch (error) {
    ElMessage.error('获取数据失败')
    console.error(error)
  }
}
const fetchUserInterest = async () => {
  if (!isInterestFormValid.value) {
    ElMessage.error('请完整填写表单信息！')
    return
  }

  try {
    const [startTime, endTime] = interestTimeRange.value
    // 调用指定的API
    const res = await axios.get('http://localhost:5000/get_news_stats', {
      params: {
        user_id: userInterestParams.value.userId,
        start_time: formatDateTime(startTime),
        end_time: formatDateTime(endTime)
      }
    })

    if (res.data.status !== 'success') {
      ElMessage.error(res.data.message || '获取数据失败')
      return
    }
    if(!res.data.data.summary.total_exposures){
      ElMessage.warning("未查询到相关信息!")
      return
    }
    userInterestData.value = res.data.data
    userInterestCategoryData.value = userInterestData.value.by_category || []
    userInterst_fetched_data.value = {
      user_id: userInterestParams.value.userId,
      start_time: formatDateTime(startTime),
      end_time:formatDateTime(endTime)
    }
    await nextTick(() => {
      renderCategoryPieChart()
      renderDwellTimeBarChart()
    })
  } catch (error) {
    ElMessage.error('获取数据失败')
    console.error(error)
  }
}

// 图表生成
const renderClickChart = () => {
  if (!clickChart.value || !newsLifecycleData.value.length) return

  // 先销毁旧图表
  const existingChart = echarts.getInstanceByDom(clickChart.value)
  if (existingChart) {
    existingChart.dispose()
  }
  const chart = echarts.init(clickChart.value)
  const option = {
    title: { text: '新闻点击量变化趋势' },
    tooltip: { trigger: 'axis' },
    legend: { data: ['点击量'] },
    xAxis: {
      type: 'category',
      name: '时间',
      smooth: true,
      data: newsLifecycleData.value.map(item => item.date)
    },
    yAxis: { type: 'value', name: '次数' },
    series: [{
      name: '点击量',
      type: 'line',
      data: newsLifecycleData.value.map(item => item.exposure_count),
      smooth: true,
      itemStyle: { color: '#5470C6' }
    }]
  }

  chart.setOption(option)
  window.addEventListener('resize', () => chart.resize())
}
const renderDwellTimeChart = () => {
  if (!dwellTimeChart.value || !newsLifecycleData.value.length) return

  // 先销毁旧图表
  const existingChart = echarts.getInstanceByDom(dwellTimeChart.value)
  if (existingChart) {
    existingChart.dispose()
  }

  const chart = echarts.init(dwellTimeChart.value)
  const option = {
    title: { text: '用户停留时间趋势' },
    tooltip: { trigger: 'axis' },
    legend: { data: ['停留时间(秒)'] },
    xAxis: {
      type: 'category',
      name: '时间',
      smooth: true,
      data: newsLifecycleData.value.map(item => item.date)
    },
    yAxis: { type: 'value', name: '时间(秒)' },
    series: [{
      name: '停留时间(秒)',
      type: 'line',
      data: newsLifecycleData.value.map(item => item.total_dwelltime),
      smooth: true,
      itemStyle: { color: '#91CC75' }
    }]
  }

  chart.setOption(option)
  window.addEventListener('resize', () => chart.resize())
}
const renderCategoryChart = () => {
  if (!categoryChart.value || !categoryTrendData.value.length) return

  const chart = echarts.init(categoryChart.value)
  const option = {
    title: { text: '新闻类别点击趋势' },
    tooltip: { trigger: 'axis' },
    legend: { data: ['点击次数'] },
    xAxis: {
      type: 'category',
      data: categoryTrendData.value.map(item => item.date)
    },
    yAxis: { type: 'value', name: '次数' },
    series: [{
      name: '点击次数',
      type: 'bar',
      data: categoryTrendData.value.map(item => item.exposure_count),
      itemStyle: { color: '#EE6666' }
    }]
  }

  chart.setOption(option)
  window.addEventListener('resize', () => chart.resize())
}
const renderCategoryPieChart = () => {
  if (!categoryPieChart.value || !userInterestCategoryData.value.length) return
  // 先销毁旧图表
  const existingChart = echarts.getInstanceByDom(categoryPieChart.value)
  if (existingChart) {
    existingChart.dispose()
  }
  const chart = echarts.init(categoryPieChart.value)
  const option = {
    title: {
      text: '用户兴趣类别分布',
      left: 'center'
    },
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      data: userInterestCategoryData.value.map(item => item.category)
    },
    series: [
      {
        name: '点击次数',
        type: 'pie',
        radius: ['50%', '70%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 10,
          borderColor: '#fff',
          borderWidth: 2
        },
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: '18',
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data: userInterestCategoryData.value.map(item => ({
          value: item.exposure_count,
          name: item.category
        }))
      }
    ]
  }

  chart.setOption(option)
  window.addEventListener('resize', () => chart.resize())
}
const renderDwellTimeBarChart = () => {
  if (!dwellTimeBarChart.value || !userInterestCategoryData.value.length) return
  // 先销毁旧图表
  const existingChart = echarts.getInstanceByDom(dwellTimeBarChart.value)
  if (existingChart) {
    existingChart.dispose()
  }
  const chart = echarts.init(dwellTimeBarChart.value)
  const option = {
    title: {
      text: '各类别平均停留时间',
      left: 'center'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    xAxis: {
      type: 'category',
      data: userInterestCategoryData.value.map(item => item.category),
      axisLabel: {
        interval: 0,
        rotate: 30
      }
    },
    yAxis: {
      type: 'value',
      name: '停留时间(秒)'
    },
    series: [
      {
        name: '平均停留时间',
        type: 'bar',
        data: userInterestCategoryData.value.map(item => item.avg_dwelltime),
        itemStyle: {
          color: function(params:any) {
            const colors = ['#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE']
            return colors[params.dataIndex % colors.length]
          }
        }
      }
    ]
  }

  chart.setOption(option)
  window.addEventListener('resize', () => chart.resize())
}

// 重置
const resetTimeRanges = () => {
  lifecycleTimeRange.value = [initialTime.value, currentTime.value]
  categoryTimeRange.value = [initialTime.value, currentTime.value]
  interestTimeRange.value = [initialTime.value, currentTime.value]
}
const resetFormData = () => {
  newsLifecycleParams.value = { newsId: '' }
  categoryParams.value = { category: '' }
  userInterestParams.value = { userId: '' }
}
const resetChartData = () => {
  newsLifecycleData.value = []
  categoryTrendData.value = []
  userInterestCategoryData.value = []
  userInterestData.value = {
    by_category: [],
    summary: {
      avg_dwelltime: 0,
      category_count: 0,
      total_exposures: 0,
      total_news: 0,
      user_count: 0
    }
  }
  lifecycle_fetched_data.value = {
    lifecycle_total_dwelltime: 0,
    lifecycle_total_clickcount:0,
    start_time:"",
    end_time:"",
    news_id:""
  }
  category_fetched_data.value = {
    category:"",
    total_clickcount:0,
    start_time:"",
    end_time:"",
  }
  userInterst_fetched_data.value = {
  }
}

watch(activeLifecycleTab, (newTab) => {
  nextTick(() => {
    if (newTab === 'click') {
      renderClickChart()
    } else {
      renderDwellTimeChart()
    }
  })
})
watch(activeInterestTab, (newTab) => {
  nextTick(() => {
    if (newTab === 'category') {
      renderCategoryPieChart()
    } else {
      renderDwellTimeBarChart()
    }
  })
})
</script>

<style scoped>
.trend-container {
  padding: 20px;
  height: 100%;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.time-control {
  display: flex;
  align-items: center;
}

.main-tabs {
  margin-top: 20px;
}

.query-card {
  margin-top: 20px;
}

.query-row {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 15px;
  flex-wrap: wrap;
}

.query-item {
  display: flex;
  align-items: center;
}

.query-label {
  margin-right: 8px;
  white-space: nowrap;
  font-size: 14px;
}

.info-container {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f8f8f8;
  border-radius: 4px;
}

.chart-container {
  height: 400px;
  margin-top: 20px;
  border: 1px solid #eee;
  border-radius: 4px;
  padding: 20px;
}

.empty-data {
  margin-top: 20px;
  border: 1px dashed #eee;
  border-radius: 4px;
  padding: 20px;
}

.empty-content {
  text-align: left;
  max-width: 500px;
  margin: 0 auto;
}

.empty-content p {
  font-weight: bold;
  margin-bottom: 8px;
}

.empty-content ul {
  margin-left: 20px;
  color: #666;
  line-height: 1.8;
}
</style>